#include "hw_rpu.h"

#define  RPU_SHA1_INST_SIZE     560
uint32_t rpu_sha1_cfg_inst[RPU_SHA1_INST_SIZE] = {
	0x4000, 0x00001b73,
	0x4004, 0x00101bf3,
	0x4008, 0x00000c13,
	0x400c, 0x00401cf3,
	0x4010, 0x008010f3,
	0x4014, 0x00000013,
	0x4018, 0x00000013,
	0x401c, 0x00000013,
	0x4020, 0x0080f093,
	0x4024, 0x00000013,
	0x4028, 0x00000013,
	0x402c, 0x00000013,
	0x4030, 0x04009863,
	0x4034, 0x00000013,
	0x4038, 0x00000013,
	0x403c, 0x00000013,
	0x4040, 0x000ca083,
	0x4044, 0x004ca103,
	0x4048, 0x008ca183,
	0x404c, 0x00cca203,
	0x4050, 0x010ca283,
	0x4054, 0x00000013,
	0x4058, 0x00000013,
	0x405c, 0x00000013,
	0x4060, 0x501ca023,
	0x4064, 0x502ca223,
	0x4068, 0x503ca423,
	0x406c, 0x504ca623,
	0x4070, 0x505ca823,
	0x4074, 0x00000013,
	0x4078, 0x00000013,
	0x407c, 0x00000013,
	0x4080, 0x000b2083,
	0x4084, 0x004b2103,
	0x4088, 0x008b2183,
	0x408c, 0x00cb2203,
	0x4090, 0x010b2283,
	0x4094, 0x014b2303,
	0x4098, 0x018b2383,
	0x409c, 0x01cb2403,
	0x40a0, 0x020b2483,
	0x40a4, 0x024b2503,
	0x40a8, 0x028b2583,
	0x40ac, 0x02cb2603,
	0x40b0, 0x030b2683,
	0x40b4, 0x034b2703,
	0x40b8, 0x038b2783,
	0x40bc, 0x03cb2803,
	0x40c0, 0x701ca023,
	0x40c4, 0x702ca223,
	0x40c8, 0x703ca423,
	0x40cc, 0x704ca623,
	0x40d0, 0x705ca823,
	0x40d4, 0x706caa23,
	0x40d8, 0x707cac23,
	0x40dc, 0x708cae23,
	0x40e0, 0x729ca023,
	0x40e4, 0x72aca223,
	0x40e8, 0x72bca423,
	0x40ec, 0x72cca623,
	0x40f0, 0x72dca823,
	0x40f4, 0x72ecaa23,
	0x40f8, 0x72fcac23,
	0x40fc, 0x730cae23,
	0x4100, 0x500ca083,
	0x4104, 0x504ca103,
	0x4108, 0x508ca183,
	0x410c, 0x50cca203,
	0x4110, 0x500ca303,
	0x4114, 0x504ca383,
	0x4118, 0x508ca403,
	0x411c, 0x50cca483,
	0x4120, 0x00401e73,
	0x4124, 0x01000f93,
	0x4128, 0x00000a93,
	0x412c, 0x00000013,
	0x4130, 0x510ca503,
	0x4134, 0x510ca283,
	0x4138, 0x600e2783,
	0x413c, 0x00401f73,
	0x4140, 0x001a8a93,
	0x4144, 0x05b0d813,
	0x4148, 0xfff14893,
	0x414c, 0x700f2583,
	0x4150, 0x0048f8b3,
	0x4154, 0x00580833,
	0x4158, 0x00317933,
	0x415c, 0x00f589b3,
	0x4160, 0x0128ea33,
	0x4164, 0x01380833,
	0x4168, 0x00020293,
	0x416c, 0x00018213,
	0x4170, 0x04215193,
	0x4174, 0x00008113,
	0x4178, 0x010a00b3,
	0x417c, 0x004f0f13,
	0x4180, 0x00000013,
	0x4184, 0x00000013,
	0x4188, 0x00000013,
	0x418c, 0xfbfa9ae3,
	0x4190, 0x05000d93,
	0x4194, 0x01400f93,
	0x4198, 0x00000013,
	0x419c, 0x600e2783,
	0x41a0, 0x00401f73,
	0x41a4, 0x00000013,
	0x41a8, 0x00000013,
	0x41ac, 0x00000013,
	0x41b0, 0x700f2583,
	0x41b4, 0x708f2603,
	0x41b8, 0x720f2683,
	0x41bc, 0x734f2703,
	0x41c0, 0x05b0d813,
	0x41c4, 0xfff14893,
	0x41c8, 0x00d74733,
	0x41cc, 0x00b64633,
	0x41d0, 0x0048f8b3,
	0x41d4, 0x00c74733,
	0x41d8, 0x00580833,
	0x41dc, 0x00317933,
	0x41e0, 0x05f75713,
	0x41e4, 0x0128ea33,
	0x41e8, 0x00020293,
	0x41ec, 0x00018213,
	0x41f0, 0x00f70733,
	0x41f4, 0x04215193,
	0x41f8, 0x001a8a93,
	0x41fc, 0x74ef2023,
	0x4200, 0x00e80833,
	0x4204, 0x00008113,
	0x4208, 0x00000013,
	0x420c, 0x004f0f13,
	0x4210, 0xfbfae0e3,
	0x4214, 0x010a00b3,
	0x4218, 0x00000013,
	0x421c, 0x00000013,
	0x4220, 0x014f8f93,
	0x4224, 0x004e0e13,
	0x4228, 0x00000013,
	0x422c, 0x00000013,
	0x4230, 0x600e2783,
	0x4234, 0x00000013,
	0x4238, 0x00000013,
	0x423c, 0x00000013,
	0x4240, 0x700f2583,
	0x4244, 0x708f2603,
	0x4248, 0x720f2683,
	0x424c, 0x734f2703,
	0x4250, 0x05b0d813,
	0x4254, 0x003148b3,
	0x4258, 0x00d74733,
	0x425c, 0x00b64633,
	0x4260, 0x0048c8b3,
	0x4264, 0x00c74733,
	0x4268, 0x00580833,
	0x426c, 0x00000013,
	0x4270, 0x05f75713,
	0x4274, 0x00000013,
	0x4278, 0x00020293,
	0x427c, 0x00018213,
	0x4280, 0x00f70733,
	0x4284, 0x04215193,
	0x4288, 0x001a8a93,
	0x428c, 0x74ef2023,
	0x4290, 0x00e80833,
	0x4294, 0x00008113,
	0x4298, 0x00000013,
	0x429c, 0x004f0f13,
	0x42a0, 0xfbfae0e3,
	0x42a4, 0x010880b3,
	0x42a8, 0x00000013,
	0x42ac, 0x00000013,
	0x42b0, 0x014f8f93,
	0x42b4, 0x004e0e13,
	0x42b8, 0x00000013,
	0x42bc, 0x00000013,
	0x42c0, 0x600e2783,
	0x42c4, 0x00000013,
	0x42c8, 0x00000013,
	0x42cc, 0x00000013,
	0x42d0, 0x700f2583,
	0x42d4, 0x708f2603,
	0x42d8, 0x720f2683,
	0x42dc, 0x734f2703,
	0x42e0, 0x05b0d813,
	0x42e4, 0x003178b3,
	0x42e8, 0x00d74733,
	0x42ec, 0x00b64633,
	0x42f0, 0x00417933,
	0x42f4, 0x00c74733,
	0x42f8, 0x00580833,
	0x42fc, 0x0041f9b3,
	0x4300, 0x05f75713,
	0x4304, 0x0128e8b3,
	0x4308, 0x00020293,
	0x430c, 0x00018213,
	0x4310, 0x00f70733,
	0x4314, 0x04215193,
	0x4318, 0x74ef2023,
	0x431c, 0x0138e8b3,
	0x4320, 0x00e80833,
	0x4324, 0x00008113,
	0x4328, 0x001a8a93,
	0x432c, 0x004f0f13,
	0x4330, 0xfbfae0e3,
	0x4334, 0x010880b3,
	0x4338, 0x00000013,
	0x433c, 0x00000013,
	0x4340, 0x014f8f93,
	0x4344, 0x004e0e13,
	0x4348, 0x00000013,
	0x434c, 0x00000013,
	0x4350, 0x600e2783,
	0x4354, 0x00000013,
	0x4358, 0x00000013,
	0x435c, 0x00000013,
	0x4360, 0x700f2583,
	0x4364, 0x708f2603,
	0x4368, 0x720f2683,
	0x436c, 0x734f2703,
	0x4370, 0x05b0d813,
	0x4374, 0x003148b3,
	0x4378, 0x00d74733,
	0x437c, 0x00b64633,
	0x4380, 0x0048c8b3,
	0x4384, 0x00c74733,
	0x4388, 0x00580833,
	0x438c, 0x00000013,
	0x4390, 0x05f75713,
	0x4394, 0x00000013,
	0x4398, 0x00020293,
	0x439c, 0x00018213,
	0x43a0, 0x00f70733,
	0x43a4, 0x04215193,
	0x43a8, 0x001a8a93,
	0x43ac, 0x74ef2023,
	0x43b0, 0x00e80833,
	0x43b4, 0x00008113,
	0x43b8, 0x00000013,
	0x43bc, 0x004f0f13,
	0x43c0, 0xfbfae0e3,
	0x43c4, 0x010880b3,
	0x43c8, 0x00000013,
	0x43cc, 0x00000013,
	0x43d0, 0x00000013,
	0x43d4, 0x00710133,
	0x43d8, 0x008181b3,
	0x43dc, 0x00920233,
	0x43e0, 0x006080b3,
	0x43e4, 0x00a282b3,
	0x43e8, 0x040b0b13,
	0x43ec, 0x040c0c13,
	0x43f0, 0x501ca023,
	0x43f4, 0x502ca223,
	0x43f8, 0x503ca423,
	0x43fc, 0x504ca623,
	0x4400, 0x505ca823,
	0x4404, 0xc77c6ee3,
	0x4408, 0x00000013,
	0x440c, 0x00000013,
	0x4410, 0x00201373,
	0x4414, 0x00000013,
	0x4418, 0x00000013,
	0x441c, 0x00000013,
	0x4420, 0x00132023,
	0x4424, 0x00232223,
	0x4428, 0x00332423,
	0x442c, 0x00432623,
	0x4430, 0x00532823,
	0x4434, 0x00000013,
	0x4438, 0x00000013,
	0x443c, 0x00000013,
	0x4440, 0x00004033,
	0x4444, 0x00004033,
	0x4448, 0x00000013,
	0x444c, 0x00000013,
	0x4450, 0x00000013,
	0x4454, 0x00000013,
	0x4458, 0x00000013,
	0x445c, 0x00000013
};

#define  RPU_SHA1_HT_SIZE		5
uint32_t rpu_sha1_cfg_ht[RPU_SHA1_HT_SIZE*2] = {
	0x000, 0x67452301,
	0x004, 0xefcdab89,
	0x008, 0x98badcfe,
	0x00c, 0x10325476,
	0x010, 0xc3d2e1f0
};

#define  RPU_SHA1_KT_SIZE		4
uint32_t rpu_sha1_cfg_kt[RPU_SHA1_KT_SIZE*2] = {
	0x600, 0x5a827999,
	0x604, 0x6ed9eba1,
	0x608, 0x8f1bbcdc,
	0x60c, 0xca62c1d6
};

int rpu_sha1_init(void __iomem *regbase)
{
	uint32_t *para_ptr;
	int para_size;
	int rpu_base = (int)(regbase - RPU_REG_OFFSET);

	rpu_stop_work(regbase);

	para_ptr  = &rpu_sha1_cfg_inst[0];
	para_size = RPU_SHA1_INST_SIZE/2;
	para_cfg(regbase, para_ptr, para_size);

	para_ptr  = &rpu_sha1_cfg_ht[0];
	para_size = RPU_SHA1_HT_SIZE;
	para_cfg(regbase, para_ptr, para_size);

	para_ptr  = &rpu_sha1_cfg_kt[0];
	para_size = RPU_SHA1_KT_SIZE;
	para_cfg(regbase, para_ptr, para_size);

	writel(rpu_base,   RPU_TCM_ADDR(regbase));
	writel(0xfffff000, RPU_TCM_MASK(regbase));
	writel(0x00000099, RPU_CACHE_BURST_SIZE(regbase));
	writel(0x00000000, RPU_CACHE_LINE_SIZE(regbase));

	return 0;
}

static int _rpu_sha1_crypto_core(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		bool				is_init)
{
	uint32_t mode_value   = 0x0;

	writel(in_len, RPU_PLAIN_SIZE(regbase));

	writel((uint32_t)out, RPU_CIPHER_ADDR(regbase));

	mode_value = readl(RPU_ENCRYPT_MODE(regbase));
	if (is_init)
		clrbit(mode_value, RPU_ENCRYPT_INIT_SIGN_BIT);
	else
		setbit(mode_value, RPU_ENCRYPT_INIT_SIGN_BIT);

	clrbit(mode_value, RPU_ENCRYPT_KEY_EXPAND_BIT);
	writel(mode_value, RPU_ENCRYPT_MODE(regbase));

	writel((uint32_t)in, RPU_PLAIN_ADDR(regbase));
	writel((uint32_t)in, RPU_CACHE_START_ADDR(regbase));

	return 0;
}

int rpu_sha1_crypto_irq(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		bool				is_init)
{
	rpu_stop_work(regbase);

	_rpu_sha1_crypto_core(
			regbase,
			in,
			in_len,
			out,
			is_init);

	rpu_start_irq(regbase);
	rpu_start_work(regbase);

	return 0;
}

int rpu_sha1_crypto_block(
		void __iomem		*regbase,
		const uint8_t		in[],
		uint32_t			in_len,
		uint8_t				out[],
		bool				is_init,
		uint32_t			loop)
{
	int loopout;

	rpu_stop_work(regbase);

	_rpu_sha1_crypto_core(
			regbase,
			in,
			in_len,
			out,
			is_init);

	rpu_stop_irq(regbase);

	rpu_start_work(regbase);

	loopout = rpu_wait_free(regbase, loop);

	rpu_stop_work(regbase);

	return loopout;
}

int rpu_sha1_iv_setup_imm(
		void __iomem		*regbase,
		uint8_t				iv[])
{
	return 0;
}

int rpu_sha1_iv_get_imm(
		void __iomem		*regbase,
		uint8_t				iv[])
{
	return 0;
}

